package org.jupiter.blog.service.service.impl;

import org.jupiter.blog.api.convertor.JupiterArticleConvertor;
import org.jupiter.blog.api.domain.JupiterArticle;
import org.jupiter.blog.api.dto.JupiterArticleDTO;
import org.jupiter.blog.api.dto.JupiterArticleQueryDTO;
import org.jupiter.blog.service.mapper.JupiterArticleMapper;
import org.jupiter.blog.service.service.JupiterArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class JupiterArticleServiceImpl implements JupiterArticleService {

	@Autowired
	private JupiterArticleMapper articleMapper;

	@Autowired
	private JupiterArticleConvertor articleConvertor;

	@Override
	public JupiterArticleDTO getById(String uuid) {
		JupiterArticle article = articleMapper.selectByUuid(uuid);
		return articleConvertor.toDto(article);
	}

	@Override
	public List<JupiterArticleDTO> getAll() {
		List<JupiterArticle> articles = articleMapper.selectAll();
		return articles.stream()
				.map(articleConvertor::toDto)
				.collect(Collectors.toList());
	}

	@Override
	public List<JupiterArticleDTO> getByPage(JupiterArticleDTO queryDTO) {
		int offset = (queryDTO.getPage() - 1) * queryDTO.getSize();
		List<JupiterArticle> articles = articleMapper.selectByPage(
				queryDTO.getTitle(), queryDTO.getCategoryId(), queryDTO.getStatus(),
				offset, queryDTO.getSize()
		);
		return articles.stream()
				.map(articleConvertor::toDto)
				.collect(Collectors.toList());
	}

	@Override
	public long getCount(JupiterArticleDTO queryDTO) {
		return articleMapper.countByQuery(
				queryDTO.getTitle(), queryDTO.getCategoryId(), queryDTO.getStatus()
		);
	}

	@Override
	@Transactional
	public void create(JupiterArticleDTO dto) {
		JupiterArticle article = articleConvertor.toEntity(dto);
		if (!StringUtils.hasText(article.getUuid())){
			article.setUuid(UUID.randomUUID().toString());
		}
		article.setCreateTime(LocalDateTime.now());
		article.setUpdateTime(LocalDateTime.now());
		articleMapper.insert(article);
	}

	@Override
	@Transactional
	public void update(JupiterArticleDTO dto) {
		JupiterArticle article = articleConvertor.toEntity(dto);
		article.setUuid(dto.getUuid());
		article.setUpdateTime(LocalDateTime.now());
		articleMapper.updateByUuidSelective(article);
	}

	@Override
	@Transactional
	public void delete(String uuid) {
		articleMapper.deleteByUuid(uuid);
	}

	@Override
	@Transactional
	public void updateStatus(String uuid, Integer status) {
		JupiterArticle article = new JupiterArticle();
		article.setUuid(uuid);
		article.setStatus(status);
		article.setUpdateTime(LocalDateTime.now());
		articleMapper.updateByUuidSelective(article);
	}

	@Override
	@Transactional
	public void updateStick(String uuid, Integer isStick) {
		JupiterArticle article = new JupiterArticle();
		article.setUuid(uuid);
		article.setIsStick(isStick);
		article.setUpdateTime(LocalDateTime.now());
		articleMapper.updateByUuidSelective(article);
	}

	@Override
	@Transactional
	public void updateRecommend(String uuid, Integer isRecommend) {
		JupiterArticle article = new JupiterArticle();
		article.setUuid(uuid);
		article.setIsRecommend(isRecommend);
		article.setUpdateTime(LocalDateTime.now());
		articleMapper.updateByUuidSelective(article);
	}

	@Override
	@Transactional
	public void updateCarousel(String uuid, Integer isCarousel) {
		JupiterArticle article = new JupiterArticle();
		article.setUuid(uuid);
		article.setIsCarousel(isCarousel);
		article.setUpdateTime(LocalDateTime.now());
		articleMapper.updateByUuidSelective(article);
	}

	@Override
	public List<JupiterArticleDTO> getPublishedArticles() {
		List<JupiterArticle> articles = articleMapper.selectPublishedArticles();
		return articles.stream()
				.map(articleConvertor::toDto)
				.collect(Collectors.toList());
	}

	@Override
	public List<JupiterArticleDTO> getStickArticles() {
		List<JupiterArticle> articles = articleMapper.selectStickArticles();
		return articles.stream()
				.map(articleConvertor::toDto)
				.collect(Collectors.toList());
	}

	@Override
	public List<JupiterArticleDTO> getRecommendArticles() {
		List<JupiterArticle> articles = articleMapper.selectRecommendArticles();
		return articles.stream()
				.map(articleConvertor::toDto)
				.collect(Collectors.toList());
	}

	@Override
	public List<JupiterArticleDTO> getCarouselArticles() {
		List<JupiterArticle> articles = articleMapper.selectCarouselArticles();
		return articles.stream()
				.map(articleConvertor::toDto)
				.collect(Collectors.toList());
	}
}
